﻿using HDFSViewer.Component;
using HDFSViewer.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.Commands;
using System.Windows.Data;
using System.Windows;
using HDFSViewer.Enum;
using HDFSViewer.View;
using System.Configuration;

namespace HDFSViewer.ViewModel
{
    public partial class MainWindowVM : NotifyObject
    {
        private MainWindow _view = null;

        public ObservableCollection<HDFSNodeModel> TreeViewDataContext { get; set; }
        private object _treeViewDataContextLock = new object();

        public ObservableCollection<OperationLogModel> LogContext { get; set; }
        private object _logContext = new object();

        private object _documentLock = new object();

        private HDFSNodeModel _selectedHDFSNodeModel = null;
        public HDFSNodeModel SelectedHDFSNodeModel
        {
            get { return _selectedHDFSNodeModel; }
            set
            {
                _selectedHDFSNodeModel = value;
                this.RaisePropertyChanged("SelectedHDFSNodeModel");
                this.RaiseDirectoryFunctionCanExecuteChanged();
                if (_selectedHDFSNodeModel.Type == NodeType.Directory && !_selectedHDFSNodeModel.IsLoaded) GetDirectoryAndFile(_selectedHDFSNodeModel);
            }
        }

        private OperationLogModel _selectedLog = null;
        public OperationLogModel SelectedLog
        {
            get { return _selectedLog; }
            set
            {
                _selectedLog = value;
                this.RaisePropertyChanged("SelectedLog");
            }
        }

        public string SelectedEncoding { get; set; }

        public int DownloadSegmentSize { get; set; }

        public SourceType SourceType { get; set; }

        public MainWindowVM(MainWindow view)
        {
            this._view = view;

            TreeViewDataContext = new ObservableCollection<HDFSNodeModel>();
            LogContext = new ObservableCollection<OperationLogModel>();

            ConnectHadoop = new DelegateCommand(DoConnectHadoop, DoCanConnectHadoop);
            ConnectHDInsight = new DelegateCommand(DoConnectHDInsight, DoCanConnectHDInsight);
            RefreshDirectory = new DelegateCommand(DoRefreshDirectory, DoCanRefreshDirectory);
            Disconnect = new DelegateCommand(DoDisconnect, DoCanDisconnect);
            ClearLog = new DelegateCommand(DoClearLog, DoCanClearLog);

            Delete = new DelegateCommand(DoDelete, DoCanDelete);
            ExpandAll = new DelegateCommand(DoExpandAll, DoCanExpandAll);
            CollapseAll = new DelegateCommand(DoCollapseAll, DoCanCollapseAll);
            AddDirectory = new DelegateCommand(DoAddDirectory, DoCanAddDirectory);
            ViewFile = new DelegateCommand(DoViewFile, DoCanViewFile);
            UploadFile = new DelegateCommand(DoUploadFile, DoCanUploadFile);
            DownloadFile = new DelegateCommand(DoDownloadFile, DoCanDownloadFile);
            AddFile = new DelegateCommand(DoAddFile, DoCanAddFile);
            AppendFile = new DelegateCommand(DoAppendFile, DoCanAppendFile);

            BindingOperations.EnableCollectionSynchronization(TreeViewDataContext, _treeViewDataContextLock);
            BindingOperations.EnableCollectionSynchronization(LogContext, _logContext);
            BindingOperations.EnableCollectionSynchronization(this._view.ldpMain.Children, _documentLock);

            DownloadSegmentSize = 1024 * 1024;
            try
            {
                DownloadSegmentSize = int.Parse(ConfigurationManager.AppSettings["DownloadSegmentSize"]);
                if (DownloadSegmentSize <= 1024) DownloadSegmentSize = 1024 * 1024;
            }
            catch { }
        }


        public void RaiseToolBarCanExecuteChanged()
        {
            this.ConnectHadoop.RaiseCanExecuteChanged();
            this.ConnectHDInsight.RaiseCanExecuteChanged();
            this.Disconnect.RaiseCanExecuteChanged();
            this.ExpandAll.RaiseCanExecuteChanged();
            this.CollapseAll.RaiseCanExecuteChanged();
        }

        public void RaiseDirectoryFunctionCanExecuteChanged()
        {
            this.ViewFile.RaiseCanExecuteChanged();
            this.AddDirectory.RaiseCanExecuteChanged();
            this.AddFile.RaiseCanExecuteChanged();
            this.UploadFile.RaiseCanExecuteChanged();
            this.DownloadFile.RaiseCanExecuteChanged();
            this.Delete.RaiseCanExecuteChanged();
            this.AppendFile.RaiseCanExecuteChanged();
            this.RefreshDirectory.RaiseCanExecuteChanged();
        }

        public void AddLog(OperationLogModel log)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                this.LogContext.Add(log);
                this.SelectedLog = log;
                this._view.lbLog.ScrollIntoView(log);
            });
        }

        public OperationLogModel AddLog(LogType type, LogStatus status, string info, string result)
        {
            OperationLogModel log = new OperationLogModel(type.ToString(), info);
            log.ChangeStatus(status, result);
            AddLog(log);
            return log;
        }

        public void NewFileDetailWindow(HDFSNodeModel model)
        {
            var document = this._view.ldpMain.Children.SingleOrDefault(lc =>
            {
                return lc.ContentId == model.QueryPath;
            });
            if (document == null)
            {
                var newdocument = new Xceed.Wpf.AvalonDock.Layout.LayoutDocument()
                {
                    ContentId = model.QueryPath,
                    Title = model.Name,
                    Content = new FileDetailControl(this, model)
                };
                this._view.ldpMain.InsertChildAt(0, newdocument);
                newdocument.IsSelected = true;
            }
            else
            {
                document.IsSelected = true;
            }
        }
    }
}